//author:dhclly
// 基础类型 · TypeScript中文网 · TypeScript——JavaScript的超集
// https://www.tslang.cn/docs/handbook/basic-types.html

const o = console.log;
//--boolean
let boolType: boolean = false;
o("boolType:", boolType);
//--number
let numberType: number = 10;
o("numberType:", numberType);

let numberTypeHex: number = 0xf;
o("numberTypeHex:", numberTypeHex);

let numberTypeBinary: number = 0b1010;
o("numberTypeBinary:", numberTypeBinary);

let numberTypeOct: number = 0o744;
o("numberTypeOct:", numberTypeOct);

//--string
let myname: string = `Gene`; //不能命名为name，会报错，和window.name定义冲突
let age: number = 37;
let sentence: string = `Hello, my name is ${myname}. \
I'll be ${age + 1} years old next month.`;
o(sentence);

//--tuple 复合类型

// Declare a tuple type
let x: [string, number];
// Initialize it
x = ["hello", 10]; // OK
o(x[0], x[1]);

// Initialize it incorrectly
//x = [10, 'hello']; // Error
//o(x[0],x[1]);

// 当访问一个越界的元素，会使用联合类型替代(新版本不能这么玩，只能用定义好的)
x[0] = "world"; // OK, 字符串可以赋值给(string | number)类型
o(x[0]);
o(x[1].toString());

//-- enum 枚举

enum Color {
  Red = 1,
  Green,
  Blue
}
let green: Color = Color.Green;
let colorName: string = Color[2];
o("clolor ", green);
o("color name ", colorName);

//-- any

let notSure: any = 4;
notSure = "maybe a string instead";
o(notSure);
notSure = false; // okay, definitely a boolean
o(notSure);

notSure = {}
notSure.ifItExists = () => { }
notSure.ifItExists(); // okay, ifItExists might exist at runtime
o('okay, ifItExists might exist at runtime')

notSure = 1.0
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)
o('okay, toFixed exists \(but the compiler doesn\'t check\)')

let prettySure: Object = 4;
//prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.

let list: any[] = [1, true, "free"];

list[1] = 100;

//-- void

function warnUser(): void {
  o("This is my warning message");
}

let unusable: void = undefined;
let unusable2: void = null;

//--Null 和 Undefined

// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;

//--Never

// 返回never的函数必须存在无法达到的终点
function n_error(message: string): never {
  throw new Error(message);
}

// 推断的返回值类型为never
function n_fail() {
  return n_error("Something failed");
}

// 返回never的函数必须存在无法达到的终点
function n_infiniteLoop(): never {
  while (true) {
  }
}

//-- Object
//d.ts
declare function create(o: object | null): void;

// create({ prop: 0 }); // OK
// create(null); // OK

// create(42); // Error
// create("string"); // Error
// create(false); // Error
// create(undefined); // Error

//-- type assert 类型转换

let someValue: any = "this is a string";
o(someValue);
let strLength: number = (<string>someValue).length;
o(strLength);
let someValue2: any = "this is a string";
o(someValue2);
let strLength2: number = (someValue2 as string).length;
o(strLength2);